home *** CD-ROM | disk | FTP | other *** search
- /*
- * npshell.c
- *
- * Netscape Client Plugin API
- * - Function that need to be implemented by plugin developers
- *
- * This file defines a "shell" plugin that plugin developers can use
- * as the basis for a real plugin. This shell just provides empty
- * implementations of all functions that the plugin can implement
- * that will be called by Netscape (the NPP_xxx methods defined in
- * npapi.h).
- *
- * dp Suresh <dp@netscape.com>
- *
- *----------------------------------------------------------------------
- * PLUGIN DEVELOPERS:
- * Implement your plugins here.
- * A sample text plugin is implemented here.
- * All the sample plugin does is displays any file with a
- * ".txt" extension in a scrolled text window. It uses Motif.
- *----------------------------------------------------------------------
- */
-
- #define XP_UNIX
-
- #include <Xm/Xm.h>
- #include "npapi.h"
-
-
- /*
- * Replace this string with the MIME type and extension fields
- * for which your plugin should be registered.
- */
-
- /*--- Start custom code */
-
- #define MIME_EXT_DESCRIPTION "text/x-movingtext:.mvtxt"
-
- /*--- End custom code */
-
- /****************************************************
- * Instance state information about the plugin.
- *
- * PLUGIN DEVELOPERS:
- * Use this struct to hold per-instance information that you'll
- * need in the various functions in this file.
- ***********************************************************************/
-
- #define LEFT 0
- #define RIGHT 1
- #define UP 2
- #define DOWN 3
-
- typedef struct _PluginInstance
- {
- Widget netscape_widget; /* The widget provided by netscape */
- Display *display; /* Netscape's display connection */
- uint16 mode; /* NP_EMBED, NP_FULL, or NP_BACKGROUND */
- uint32 width, height;
- /*--- Start custom code */
-
- char *string;
- int direction; /* LEFT = 0, RIGHT = 1, UP = 2, DOWN = 3 */
- int len;
- GC gc;
- int x, y, bannerWidth, bannerHeight, ascent, descent;
- XFontStruct *font;
- XtIntervalId timerId;
- XtAppContext appContext;
- char *fontName;
-
- /*--- End custom code */
-
- } PluginInstance;
-
-
- static void DoAnimation(XtPointer clientData, XtIntervalId *id );
-
- /***********************************************************************
- *
- * Empty implementations of plugin API functions
- *
- * PLUGIN DEVELOPERS:
- * You will need to implement these functions as required by your
- * plugin.
- *
- ***********************************************************************/
-
- char *
- NPP_GetMIMEDescription(void)
- {
- return( MIME_EXT_DESCRIPTION );
- }
-
- NPError
- NPP_Initialize(void)
- {
- return NPERR_NO_ERROR;
- }
-
- void
- NPP_Shutdown(void)
- {
- }
-
-
- NPError
- NPP_New(NPMIMEType pluginType,
- NPP instance,
- uint16 mode,
- int16 argc,
- char* argn[],
- char* argv[],
- NPSavedData* saved)
- {
- PluginInstance* This;
-
- if (instance == NULL)
- return NPERR_INVALID_INSTANCE_ERROR;
-
- instance->pdata = NPN_MemAlloc(sizeof(PluginInstance));
-
- This = (PluginInstance*) instance->pdata;
-
- if (This != NULL)
- {
- int i;
- This->netscape_widget = NULL;
- This->display = NULL;
- This->mode = mode; /* mode is NP_EMBED, NP_FULL, or NP_BACKGROUND (see npapi.h) */
- This->width = 0;
- This->height = 0;
-
- /* *Developers*: Initialize fields of your plugin
- * instance data here. If the NPSavedData is non-
- * NULL, you can use that data (returned by you from
- * NPP_Destroy to set up the new plugin instance.
- */
-
- /*--- Start custom code */
-
- This->string = NULL;
- This->direction = 0;
- This->len = 0;
- This->timerId = 0;
- This->x = 0;
- This->y = 0;
- This->bannerWidth = 0;
-
- This->fontName = "fixed";
-
- /* get any args we recognize from the html file */
-
- for(i = 0; i < argc; i++)
- {
- if(!strcmp(argn[i], "FONT"))
- This->fontName = XtNewString(argv[i]);
-
- if(!strcmp(argn[i], "DIRECTION"))
- {
- if(!strcmp(argv[i], "LEFT"))
- This->direction = LEFT;
- if(!strcmp(argv[i], "RIGHT"))
- This->direction = RIGHT;
- if(!strcmp(argv[i], "UP"))
- This->direction = UP;
- if(!strcmp(argv[i], "DOWN"))
- This->direction = DOWN;
- }
- }
-
- /*--- End custom code */
-
- return NPERR_NO_ERROR;
- }
- else
- return NPERR_OUT_OF_MEMORY_ERROR;
- }
-
-
- NPError
- NPP_Destroy(NPP instance, NPSavedData** save)
- {
- PluginInstance* This;
-
- if (instance == NULL)
- return NPERR_INVALID_INSTANCE_ERROR;
-
- This = (PluginInstance*) instance->pdata;
-
- /* PLUGIN DEVELOPERS:
- * If desired, call NP_MemAlloc to create a
- * NPSavedDate structure containing any state information
- * that you want restored if this plugin instance is later
- * recreated.
- */
-
- if (This != NULL) {
- NPN_MemFree(instance->pdata);
- instance->pdata = NULL;
-
- /*--- Start custom code */
-
- /* Stream is closed, we have the data, so start a timer to
- * call the draw routine
- */
-
- if(This->timerId)
- XtRemoveTimeOut(This->timerId);
- This->timerId = 0;
-
- /*--- End custom code */
- }
-
- return NPERR_NO_ERROR;
- }
-
-
-
- NPError
- NPP_SetWindow(NPP instance, NPWindow* window)
- {
- PluginInstance* This;
-
- Pixel bg, fg;
- int num_fonts;
-
- if (instance == NULL)
- return NPERR_INVALID_INSTANCE_ERROR;
-
- This = (PluginInstance*) instance->pdata;
-
- /*
- * PLUGIN DEVELOPERS:
- * Before setting window to point to the
- * new window, you may wish to compare the new window
- * info to the previous window (if any) to note window
- * size changes, etc.
- */
-
- This->display = ((NPSetWindowCallbackStruct *)window->ws_info)->display;
- This->netscape_widget = XtWindowToWidget(This->display, (Window)window->window);
- This->width = window->width;
- This->height = window->height;
-
- /*--- Start custom code */
-
- /* We need lots of info to draw a string */
-
- This->appContext = XtWidgetToApplicationContext(This->netscape_widget);
-
- This->gc = XCreateGC(This->display,
- (Window)window->window, 0,
- (XGCValues *) NULL);
-
- XtVaGetValues(This->netscape_widget,
- XmNbackground, &bg,
- XmNforeground, &fg,
- NULL);
-
- /*
- * Cheat - set the netscape window's border to 0 so we don't see the
- * black outlines
- */
-
- XtVaSetValues(This->netscape_widget,
- XmNborderWidth, 0,
- NULL);
-
- XSetForeground(This->display, This->gc, fg);
- XSetBackground(This->display, This->gc, bg);
-
- XListFonts(This->display, This->fontName, 1, &num_fonts);
-
-
- if (num_fonts)
- {
- This->font = XLoadQueryFont(This->display, This->fontName);
- XSetFont(This->display, This->gc, This->font->fid);
- }
-
- /*--- End custom code */
-
- return NPERR_NO_ERROR;
- }
-
-
- NPError
- NPP_NewStream(NPP instance,
- NPMIMEType type,
- NPStream *stream,
- NPBool seekable,
- uint16 *stype)
- {
- PluginInstance* This;
-
- if (instance == NULL)
- return NPERR_INVALID_INSTANCE_ERROR;
-
- This = (PluginInstance*) instance->pdata;
-
- /*--- Start custom code */
-
- /* We want a stream of data */
-
- *stype = NP_NORMAL;
-
- /*--- End custom code */
-
- return NPERR_NO_ERROR;
- }
-
-
- /* PLUGIN DEVELOPERS:
- * These next 2 functions are directly relevant in a plug-in which
- * handles the data in a streaming manner. If you want zero bytes
- * because no buffer space is YET available, return 0. As long as
- * the stream has not been written to the plugin, Navigator will
- * continue trying to send bytes. If the plugin doesn't want them,
- * just return some large number from NPP_WriteReady(), and
- * ignore them in NPP_Write(). For a NP_ASFILE stream, they are
- * still called but can safely be ignored using this strategy.
- */
-
- int32 STREAMBUFSIZE = 0X0FFFFFFF; /* If we are reading from a file in NPAsFile
- * mode so we can take any size stream in our
- * write call (since we ignore it) */
-
- int32
- NPP_WriteReady(NPP instance, NPStream *stream)
- {
- PluginInstance* This;
- if (instance != NULL)
- This = (PluginInstance*) instance->pdata;
-
- /* Number of bytes ready to accept in NPP_Write() */
- return STREAMBUFSIZE;
- }
-
-
- int32
- NPP_Write(NPP instance, NPStream *stream, int32 offset, int32 len, void *buffer)
- {
- if (instance != NULL)
- {
- PluginInstance* This = (PluginInstance*) instance->pdata;
-
-
- /*--- Start custom code */
-
- /* Just get the data. If there is a lot, we'll get it in
- * pieces, so be prepared to append
- */
-
- This->string = XtRealloc(This->string, This->len + len + 2);
-
- strncpy(&(This->string[This->len]), buffer, len);
-
- This->len += len;
-
- This->string[This->len] = '\0';
-
- /*--- End custom code */
-
- }
-
- return len; /* The number of bytes accepted */
- }
-
-
- NPError
- NPP_DestroyStream(NPP instance, NPStream *stream, NPError reason)
- {
- PluginInstance* This;
- XCharStruct bounds;
- int direction, ascent, descent;
-
- if (instance == NULL)
- return NPERR_INVALID_INSTANCE_ERROR;
- This = (PluginInstance*) instance->pdata;
-
- /*--- Start custom code */
-
- /* OK, ready to go, find out how big the string is,
- * and initialize the string's position
- */
-
- XTextExtents(This->font, This->string, This->len,
- &direction, &ascent, &descent, &bounds);
-
- This->bannerWidth = bounds.width;
- This->bannerHeight = bounds.ascent + bounds.descent;
- This->ascent = bounds.ascent;
- This->descent = bounds.descent;
-
- if(This->direction == LEFT)
- {
- This->x = This->width;
- This->y = This->bannerHeight;
- }
- else if(This->direction == RIGHT)
- {
- This->x = -This->bannerWidth;
- This->y = This->bannerHeight;
- }
- else if(This->direction == DOWN)
- {
- This->x = 0;
- This->y = 0;
- }
- else if(This->direction == UP)
- {
- This->x = 0;
- This->y = This->bannerHeight + This->height;
- }
-
- This->timerId = XtAppAddTimeOut(This->appContext,
- 100,
- DoAnimation,
- (XtPointer)instance);
-
- /*--- End custom code */
-
- return NPERR_NO_ERROR;
- }
-
-
- void
- NPP_StreamAsFile(NPP instance, NPStream *stream, const char* fname)
- {
- PluginInstance* This;
- if (instance != NULL)
- This = (PluginInstance*) instance->pdata;
- }
-
-
- void
- NPP_Print(NPP instance, NPPrint* printInfo)
- {
- if(printInfo == NULL)
- return;
-
- if (instance != NULL) {
- PluginInstance* This = (PluginInstance*) instance->pdata;
-
- if (printInfo->mode == NP_FULL) {
- /*
- * PLUGIN DEVELOPERS:
- * If your plugin would like to take over
- * printing completely when it is in full-screen mode,
- * set printInfo->pluginPrinted to TRUE and print your
- * plugin as you see fit. If your plugin wants Netscape
- * to handle printing in this case, set
- * printInfo->pluginPrinted to FALSE (the default) and
- * do nothing. If you do want to handle printing
- * yourself, printOne is true if the print button
- * (as opposed to the print menu) was clicked.
- * On the Macintosh, platformPrint is a THPrint; on
- * Windows, platformPrint is a structure
- * (defined in npapi.h) containing the printer name, port,
- * etc.
- */
-
- void* platformPrint =
- printInfo->print.fullPrint.platformPrint;
- NPBool printOne =
- printInfo->print.fullPrint.printOne;
-
- /* Do the default*/
- printInfo->print.fullPrint.pluginPrinted = FALSE;
- }
- else { /* If not fullscreen, we must be embedded */
- /*
- * PLUGIN DEVELOPERS:
- * If your plugin is embedded, or is full-screen
- * but you returned false in pluginPrinted above, NPP_Print
- * will be called with mode == NP_EMBED. The NPWindow
- * in the printInfo gives the location and dimensions of
- * the embedded plugin on the printed page. On the
- * Macintosh, platformPrint is the printer port; on
- * Windows, platformPrint is the handle to the printing
- * device context.
- */
-
- NPWindow* printWindow =
- &(printInfo->print.embedPrint.window);
- void* platformPrint =
- printInfo->print.embedPrint.platformPrint;
- }
- }
- }
-
- /*--- Start custom code */
-
- static void DoAnimation(XtPointer clientData, XtIntervalId *id )
- {
- NPP instance = (NPP)clientData;
- PluginInstance* This = (PluginInstance*) instance->pdata;
-
- /* Draw the string */
-
- XDrawImageString(This->display, XtWindow(This->netscape_widget),
- This->gc, This->x,
- This->y,
- This->string, This->len);
-
- /* Clear any space left to the sides */
-
- if(This->x > 0)
- XClearArea(This->display, XtWindow(This->netscape_widget),
- 0, 0,
- This->x,
- This->height, FALSE);
-
- XClearArea(This->display, XtWindow(This->netscape_widget),
- This->x + This->bannerWidth, 0,
- This->width,
- This->height, FALSE);
-
-
- /* Compute the next location of the string. Also clear any space
- left to the top or bottom for vertical text*/
-
- if(This->direction == LEFT)
- {
- This->x -= 10;
-
- if(This->x + This->bannerWidth <= 0)
- This->x = This->bannerWidth;
- }
- else if(This->direction == RIGHT)
- {
- This->x += 10;
-
- if((int)This->x > (int)This->width)
- This->x = -This->bannerWidth;
- }
- else if(This->direction == DOWN)
- {
- XClearArea(This->display, XtWindow(This->netscape_widget),
- 0, 0,
- This->width,
- This->y - This->ascent, FALSE);
-
- This->y += 2;
-
- if(This->y + This->bannerHeight > This->height)
- This->y = 0;
- }
- else if(This->direction == UP)
- {
- XClearArea(This->display, XtWindow(This->netscape_widget),
- 0, This->y + This->descent,
- 0,
- This->height, FALSE);
-
- This->y -= 2;
-
- if((int)This->y < - (int)This->bannerHeight)
- This->y = This->height;
- }
-
- /* Install a new timer for the next round */
-
- This->timerId = XtAppAddTimeOut(This->appContext, 100, DoAnimation, (XtPointer)instance);
-
- }
-
- /*--- End custom code */
-
-